home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / asxsrc.arc / ASMAIN.C < prev    next >
C/C++ Source or Header  |  1991-06-10  |  10KB  |  626 lines

  1. /* asmain.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15.  
  16.  
  17. VOID
  18. main(argc, argv)
  19. char *argv[];
  20. {
  21.     register char *p;
  22.     register c, i;
  23.     struct area *ap;
  24.     FILE *afile();
  25.  
  26.     inpfil = -1;
  27.     for (i=1; i<argc; ++i) {
  28.         p = argv[i];
  29.         if (*p == '-') {
  30.             ++p;
  31.             while (c = *p++)
  32.                 switch(c) {
  33.  
  34.                 case 'a':
  35.                 case 'A':
  36.                     ++aflag;
  37.                     break;
  38.  
  39.                 case 'g':
  40.                 case 'G':
  41.                     ++gflag;
  42.                     break;
  43.  
  44.                 case 'l':
  45.                 case 'L':
  46.                     ++lflag;
  47.                     break;
  48.  
  49.                 case 'o':
  50.                 case 'O':
  51.                     ++oflag;
  52.                     break;
  53.  
  54.                 case 's':
  55.                 case 'S':
  56.                     ++sflag;
  57.                     break;
  58.  
  59.                 case 'x':
  60.                 case 'X':
  61.                     xflag = 0;
  62.                     break;
  63.  
  64.                 case 'q':
  65.                 case 'Q':
  66.                     xflag = 1;
  67.                     break;
  68.  
  69.                 case 'd':
  70.                 case 'D':
  71.                     xflag = 2;
  72.                     break;
  73.  
  74.                 default:
  75.                     usage();
  76.                 }
  77.         } else {
  78.             if (++inpfil == MAXFIL) {
  79.                 fprintf(stderr, "too many input files\n");
  80.                 exit(1);
  81.             }
  82.             sfp[inpfil] = afile(p, "", 0);
  83.             if (inpfil == 0) {
  84.                 if (lflag)
  85.                     lfp = afile(p, "lst", 1);
  86.                 if (oflag)
  87.                     ofp = afile(p, "rel", 1);
  88.                 if (sflag)
  89.                     tfp = afile(p, "sym", 1);
  90.             }
  91.         }
  92.     }
  93.     if (inpfil < 0)
  94.         usage();
  95.     syminit();
  96.     for (pass=0; pass<3; ++pass) {
  97.         if (gflag && pass == 1)
  98.             symglob();
  99.         if (aflag && pass == 1)
  100.             allglob();
  101.         if (oflag && pass == 2)
  102.             outgsd();
  103.         flevel = 0;
  104.         tlevel = 0;
  105.         ifcnd[0] = 0;
  106.         iflvl[0] = 0;
  107.         radix = 10;
  108.         line = 0;
  109.         page = 0;
  110.         stb[0] = 0;
  111.         lop  = NLPP;
  112.         cfile = 0;
  113.         incfil = -1;
  114.         for (i = 0; i <= inpfil; i++)
  115.             rewind(sfp[i]);
  116.         ap = areap;
  117.         while (ap) {
  118.             ap->a_fuzz = 0;
  119.             ap->a_size = 0;
  120.             ap = ap->a_ap;
  121.         }
  122.         fuzz = 0;
  123.         dot->s_addr = 0;
  124.         dot->s_area = dca;
  125.         symp = dot;
  126.         minit();
  127.         while (getline()) {
  128.             ++line;
  129.             cp = cb;
  130.             ep = eb;
  131.             ip = ib;
  132.             if (setjmp(jump_env) == 0)
  133.                 asmbl();
  134.             if (pass == 2) {
  135.                 diag();
  136.                 list();
  137.             }
  138.         }
  139.         newdot(dot->s_area); /* Flush area info */
  140.         if (flevel || tlevel)
  141.             err('i');
  142.     }
  143.     if (oflag)
  144.         outchk(HUGE, HUGE);  /* Flush */
  145.     if (sflag) {
  146.         lstsym(tfp);
  147.     } else
  148.     if (lflag) {
  149.         lstsym(lfp);
  150.     }
  151. }
  152.  
  153. VOID
  154. asmbl()
  155. {
  156.     register struct mne *mp;
  157.     register struct sym *sp;
  158.     register struct tsym *tp;
  159.     register c;
  160.     struct area  *ap;
  161.     struct expr e1;
  162.     char id[NCPS];
  163.     char opt[NCPS];
  164.     char fn[FILSPC];
  165.     char *p;
  166.     int d, n, uaf, uf;
  167.  
  168.     laddr = dot->s_addr;
  169.     lmode = SLIST;
  170. loop:
  171.     if ((c=endline()) == 0) { return; }
  172.     if (ctype[c] == DIGIT) {
  173.         if (flevel)
  174.             return;
  175.         n = 0;
  176.         while ((d = digit(c, 10)) >= 0) {
  177.             n = 10*n + d;
  178.             c = get();
  179.         }
  180.         if (c != '$' || get() != ':')
  181.             qerr();
  182.         tp = symp->s_tsym;
  183.         if (pass == 0) {
  184.             while (tp) {
  185.                 if (n == tp->t_num) {
  186.                     tp->t_flg |= S_MDF;
  187.                     break;
  188.                 }
  189.                 tp = tp->t_lnk;
  190.             }
  191.             if (tp == NULL) {
  192.                 tp=(struct tsym *) new (sizeof(struct tsym));
  193.                 tp->t_lnk = symp->s_tsym;
  194.                 tp->t_num = n;
  195.                 tp->t_area = dot->s_area;
  196.                 tp->t_addr = dot->s_addr;
  197.                 symp->s_tsym = tp;
  198.             }
  199.         } else {
  200.             while (tp) {
  201.                 if (n == tp->t_num) {
  202.                     break;
  203.                 }
  204.                 tp = tp->t_lnk;
  205.             }
  206.             if (tp) {
  207.                 if (pass == 1) {
  208.                     fuzz = tp->t_addr - dot->s_addr;
  209.                     tp->t_area = dot->s_area;
  210.                     tp->t_addr = dot->s_addr;
  211.                 } else {
  212.                     phase(tp->t_area, tp->t_addr);
  213.                     if (tp->t_flg & S_MDF)
  214.                         err('m');
  215.                 }
  216.             } else {
  217.                 err('u');
  218.             }
  219.         }
  220.         goto loop;
  221.     }
  222.     if (ctype[c] != LETTER) 
  223.         if (flevel) {
  224.             return;
  225.         } else {
  226.             qerr();
  227.         }
  228.     getid(id, c);
  229.     c = getnb();
  230.     if (c == ':') {
  231.         if (flevel)
  232.             return;
  233.         if ((c = get()) != ':') {
  234.             unget(c);
  235.             c = 0;
  236.         }
  237.         symp = lookup(id);
  238.         if (symp == dot)
  239.             err('.');
  240.         if (pass == 0)
  241.             if (symp->s_type != S_NEW &&
  242.                (symp->s_flag & S_ASG) == 0)
  243.                 symp->s_flag |= S_MDF;
  244.         if (pass != 2) {
  245.             fuzz = symp->s_addr - dot->s_addr;
  246.             symp->s_type = S_USER;
  247.             symp->s_area = dot->s_area;
  248.             symp->s_addr = dot->s_addr;
  249.         } else {
  250.             if (symp->s_flag & S_MDF)
  251.                 err('m');
  252.             phase(symp->s_area, symp->s_addr);
  253.         }
  254.         if (c) {
  255.             symp->s_flag |= S_GBL;
  256.         }
  257.         lmode = ALIST;
  258.         goto loop;
  259.     }
  260.     if (c == '=') {
  261.         if (flevel)
  262.             return;
  263.         if ((c = get()) != '=') {
  264.             unget(c);
  265.             c = 0;
  266.         }
  267.         expr(&e1, 0);
  268.         sp = lookup(id);
  269.         if (sp == dot) {
  270.             outall();
  271.             if (e1.e_flag || e1.e_base.e_ap != dot->s_area)
  272.                 err('.');
  273.         } else
  274.         if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
  275.             err('m');
  276.         }
  277.         sp->s_type = S_USER;
  278.         sp->s_area = e1.e_base.e_ap;
  279.         sp->s_addr = laddr = e1.e_addr;
  280.         sp->s_flag |= S_ASG;
  281.         if (c) {
  282.             sp->s_flag |= S_GBL;
  283.         }
  284.         lmode = ALIST;
  285.         goto loop;
  286.     }
  287.     unget(c);
  288.     lmode = flevel ? SLIST : CLIST;
  289.     if ((mp = mlookup(id)) == NULL) {
  290.         if (!flevel)
  291.             err('o');
  292.         return;
  293.     }
  294.     switch (mp->m_type) {
  295.  
  296.     case S_IF:
  297.         n = absexpr();
  298.         if (tlevel < MAXIF) {
  299.             ++tlevel;
  300.             ifcnd[tlevel] = n;
  301.             iflvl[tlevel] = flevel;
  302.             if (n == 0) {
  303.                 ++flevel;
  304.             }
  305.         } else {
  306.             err('i');
  307.         }
  308.         lmode = ALIST;
  309.         laddr = n;
  310.         return;
  311.  
  312.     case S_ELSE:
  313.         if (ifcnd[tlevel]) {
  314.             if (++flevel > (iflvl[tlevel]+1)) {
  315.                 err('i');
  316.             }
  317.         } else {
  318.             if (--flevel < iflvl[tlevel]) {
  319.                 err('i');
  320.             }
  321.         }
  322.         lmode = SLIST;
  323.         return;
  324.  
  325.     case S_ENDIF:
  326.         if (tlevel) {
  327.             flevel = iflvl[tlevel--];
  328.         } else {
  329.             err('i');
  330.         }
  331.         lmode = SLIST;
  332.         return;
  333.  
  334.     case S_PAGE:
  335.         lop = NLPP;
  336.         lmode = NLIST;
  337.         return;
  338.  
  339.     default:
  340.         break;
  341.     }
  342.     if (flevel)
  343.         return;
  344.     switch (mp->m_type) {
  345.  
  346.     case S_EVEN:
  347.         outall();
  348.         dot->s_addr = (dot->s_addr + 1) & ~1;
  349.         lmode = SLIST;
  350.         break;
  351.  
  352.     case S_ODD:
  353.         outall();
  354.         dot->s_addr |= 1;
  355.         lmode = SLIST;
  356.         break;
  357.  
  358.     case S_BYTE:
  359.     case S_WORD:
  360.         do {
  361.             expr(&e1, 0);
  362.             if (mp->m_type == S_BYTE) {
  363.                 outrb(&e1, 0);
  364.             } else {
  365.                 outrw(&e1, 0);
  366.             }
  367.         } while ((c = getnb()) == ',');
  368.         unget(c);
  369.         break;
  370.  
  371.     case S_ASCII:
  372.     case S_ASCIZ:
  373.         if ((d = getnb()) == '\0')
  374.             qerr();
  375.         while ((c = getmap(d)) >= 0)
  376.             outab(c);
  377.         if (mp->m_type == S_ASCIZ)
  378.             outab(0);
  379.         break;
  380.  
  381.     case S_BLK:
  382.         expr(&e1, 0);
  383.         outall();
  384.         dot->s_addr += e1.e_addr*mp->m_valu;
  385.         break;
  386.  
  387.     case S_TITLE:
  388.         p = tb;
  389.         if (c = getnb()) {
  390.             do {
  391.                 if (p < &tb[NTITL-1])
  392.                     *p++ = c;
  393.             } while (c = get());
  394.         }
  395.         *p = 0;
  396.         unget(c);
  397.         lmode = SLIST;
  398.         break;
  399.  
  400.     case S_SBTL:
  401.         p = stb;
  402.         if (c = getnb()) {
  403.             do {
  404.                 if (p < &stb[NSBTL-1])
  405.                     *p++ = c;
  406.             } while (c = get());
  407.         }
  408.         *p = 0;
  409.         unget(c);
  410.         lmode = SLIST;
  411.         break;
  412.  
  413.     case S_MODUL:
  414.         getid(id, -1);
  415.         if (pass == 0) {
  416.             if (module[0])
  417.                 err('m');
  418.             strncpy(module, id, NCPS);
  419.         }
  420.         lmode = SLIST;
  421.         break;
  422.  
  423.     case S_GLOBL:
  424.         do {
  425.             getid(id, -1);
  426.             sp = lookup(id);
  427.             sp->s_flag |= S_GBL;
  428.         } while ((c = getnb()) == ',');
  429.         unget(c);
  430.         lmode = SLIST;
  431.         break;
  432.  
  433.     case S_DAREA:
  434.         getid(id, -1);
  435.         uaf = 0;
  436.         uf  = A_CON|A_REL;
  437.         if ((c = getnb()) == '(') {
  438.             do {
  439.                 getid(opt, -1);
  440.                 mp = mlookup(opt);
  441.                 if (mp && mp->m_type == S_ATYP) {
  442.                     ++uaf;
  443.                     uf |= mp->m_valu;
  444.                 } else {
  445.                     err('u');
  446.                 }
  447.             } while ((c = getnb()) == ',');
  448.             if (c != ')')
  449.                 qerr();
  450.         } else {
  451.             unget(c);
  452.         }
  453.         if (ap = alookup(id)) {
  454.             if (uaf && uf != ap->a_flag)
  455.                 err('m');
  456.         } else {
  457.             ap = (struct area *) new (sizeof(struct area));
  458.             ap->a_ap = areap;
  459.             strncpy(ap->a_id, id, NCPS);
  460.             ap->a_ref = areap->a_ref + 1;
  461.             ap->a_flag = uaf ? uf : (A_CON|A_REL);
  462.             areap = ap;
  463.         }
  464.         newdot(ap);
  465.         lmode = SLIST;
  466.         break;
  467.  
  468.     case S_ORG:
  469.         if (dot->s_area->a_flag & A_ABS) {
  470.             outall();
  471.             dot->s_addr = absexpr();
  472.         } else {
  473.             err('o');
  474.         }
  475.         lmode = SLIST;
  476.         break;
  477.  
  478.     case S_RADIX:
  479.         if (more()) {
  480.             switch (getnb()) {
  481.             case 'b':
  482.             case 'B':
  483.                 radix = 2;
  484.                 break;
  485.             case '@':
  486.             case 'o':
  487.             case 'O':
  488.             case 'q':
  489.             case 'Q':
  490.                 radix = 8;
  491.                 break;
  492.             case 'd':
  493.             case 'D':
  494.                 radix = 10;
  495.                 break;
  496.             case 'h':
  497.             case 'H':
  498.             case 'x':